package com.hyl.gulimall.order;

import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;

/**
 * RabbitMQ
 * 1.引入的amqp，RabbitAutoConfiguration就会生效
 * 2. 向容器中自动配置了
 *      RabbitTemplate
 *      AmqpAdmin
 *          i. 用于创建Exchange、Queue、Binding
 *      CachingConnectionFacoty
 *      RabbitMessagingTemplate
 * 3. 所有属性都是在RabbitProperties类中定义，以spring.rabbitmq前缀开头，在配置文件中配置
 * 4. @EnableRabbit（该注解监听消息必须，而创建交换机、绑定、队列不必须）
 *
 * 5.@RabbitLisener 可以标注在类或方法上，标识监听哪个队列
 *   @RabbitHandler 标注在方法上，区分接受不同的消息类型
 *   监听消息，方法的参数类型可以参照以下
 *      i. Message message：原生消息详细信息 头+体
 *      ii. T<> 指定消息体的类型
 *      iii. Channel channel当前传输数据的通道
 *
 * 6.Queue可以供很多人监听，只要收到消息，队列就删除消息，看以下场景
 *      i. 订单服务启动很多个，同一个消息，只能有一个客户端收到
 *      ii. 只有一个消息完全处理完，才能接受下一个消息
 *
 * Spring-boot事务
 * 在同一个类里面，编写两个方法，内部调用的时候，会导致事务设置失效。原因是没有用到代理对象的缘故。（本类方法调用）
 * 解决：
 *      i.导入spring-boot-starter-aop 引入AspectJ
 *      ii. @EnableTransactionManagement(proxyTargetClass = true) 开启AspectJ动态代理功能（静态代理？）
 *      iii. @EnableAspectJAutoProxy(exposeProxy=true) 对外暴露代理对象
 *      iv. AopContext.currentProxy() 调用方法
 *
 * 分布式事务
 * 1. Seata（不适合于高并发模式，在商品上架场景中比较适用）
 *
 */

@EnableAspectJAutoProxy(exposeProxy = true)
@EnableRabbit
@EnableFeignClients
@EnableRedisHttpSession
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallOrderApplication.class, args);
    }

}
